package cn.edu.csust.coursecard.service.impl;

import cn.edu.csust.coursecard.dao.entity.Admin;
import cn.edu.csust.coursecard.dao.entity.Notice;
import cn.edu.csust.coursecard.common.CodeEnum;
import cn.edu.csust.coursecard.common.ReturnData;
import cn.edu.csust.coursecard.dao.AdminMapper;
import cn.edu.csust.coursecard.dao.dto.MuteInfo;
import cn.edu.csust.coursecard.dao.dto.RedisKeyConstant;
import cn.edu.csust.coursecard.exception.BaseException;
import cn.edu.csust.coursecard.service.AdminService;
import cn.edu.csust.coursecard.service.NoticeService;
import cn.edu.csust.coursecard.service.StuInfoService;
import cn.edu.csust.coursecard.utils.TokenUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
public class AdminServiceImpl implements AdminService {
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;
    @Autowired
    private AdminMapper adminMapper;
    @Autowired
    private TokenUtils tokenUtils;
    @Autowired
    private NoticeService noticeService;
    @Autowired
    private StuInfoService stuInfoService;
    

    @Override
    public ReturnData login(String username, String password) {
        Admin admin = adminMapper.selectByUsername(username);
        if(Objects.isNull(admin)){
            throw new BaseException(CodeEnum.REQUEST_FAILED.getCode(),"没有该管理员！" );
        }
        if(!admin.getPassword().equals(password)){
            throw new BaseException(CodeEnum.REQUEST_FAILED.getCode(),"密码错误！" );
        }
        String token = tokenUtils.generateToken(admin.getId(),true);
        Map<String,Object> map = new HashMap<>();
        map.put("token",token);
        return ReturnData.success(map);
    }

    @Override
    @Transactional
    public ReturnData mute(Integer userId, Integer muteDay) {
        redisTemplate.opsForValue().set(RedisKeyConstant.MUTE + userId,true,muteDay, TimeUnit.DAYS);
        Notice notice = new Notice();
        notice.setContent("你已被禁言" + muteDay + "天");
        notice.setUserId(userId);
        noticeService.addNotice(notice);
        return ReturnData.success();
    }
    
    @Override
    @Transactional
    public void cancelMute(Integer userId) {
        Boolean hasKey = redisTemplate.hasKey(RedisKeyConstant.MUTE + userId);
        if(hasKey == null || !hasKey){
            throw new BaseException(CodeEnum.PARAM_ERROR.getCode(), "该用户未被禁言");
        }
        redisTemplate.delete(RedisKeyConstant.MUTE + userId);
        Notice notice = new Notice();
        notice.setContent("你已被解除禁言");
        notice.setUserId(userId);
        noticeService.addNotice(notice);
    }
    
    @Override
    public List<MuteInfo> getMuteUser() {
        Set<String> keys = redisTemplate.keys(RedisKeyConstant.MUTE + "*");
        List<MuteInfo> muteInfos = new ArrayList<>();
        if(!CollectionUtils.isEmpty(keys)){
            keys.forEach(key -> {
                Integer userId = getUserIdFromRedisKey(key);
                Long expire = redisTemplate.getExpire(key);
                muteInfos.add(new MuteInfo(stuInfoService.getUserInfo(userId),new Date(System.currentTimeMillis() + expire * 1000)));
            });
        }
        return muteInfos;
    }
    
    private Integer getUserIdFromRedisKey(String key){
        return Integer.valueOf(key.substring(key.lastIndexOf(':') + 1));
    }
    
    
}
